import { Form, FormField, FormSubmit, IFormInstance } from "solid-form-context";
import {
  createEffect,
  createResource,
  createSignal,
  ErrorBoundary,
  For,
  on,
  onCleanup,
} from "solid-js";
import { Table, IndexColumn, TableColumn } from "solid-table-context";
import {
  Dialog,
  DialogAction,
  DialogCloseButton,
  DialogHeader,
  useDialog,
  useDialogShell,
} from "~/components/Dialog";
import { DateTimeColumn } from "~/components/table";
import { useClientApi, useServicesApi } from "~/services";
import { SaveServiceRequest, ServiceDto } from "~/services/client";
import { handleException } from "~/services/utils";
import ServiceEditForm from "./components/ServiceEditForm";
import { SolidSwal2Toast } from "~/components/SolidSwal2";
import Loading from "~/components/Loading";
import { Modal } from "~/components/Modal";
// import Dialog, { useContext } from "@corvu/dialog";
import { FaSolidArrowRotateRight, FaSolidPencil } from "solid-icons/fa";
import { FormInputText } from "~/components/form";
import { is_null_or_undefined } from "~/utils/object";

const ServiceEditModalChildren = (props: {
  data?: ServiceDto;
  onSaved?: () => void;
}) => {
  // const ctx = useContext();
  const shell = useDialogShell();
  const [loading, setLoading] = createSignal(false);

  const handleSaveService = (service: ServiceDto) => {
    setLoading(true);
    useClientApi()
      .saveService(SaveServiceRequest.fromJS(service))
      .then(() => {
        props.onSaved?.();
        return SolidSwal2Toast.fire({
          icon: "success",
          title: "保存成功",
          target: shell.ref(),
        }).then(() => {
          shell?.close();
        });
        // ctx.setOpen(false);
      })
      .catch((err) => handleException(err, { target: shell.ref() }))
      .finally(() => setLoading(false));
  };

  const [form, setForm] = createSignal<IFormInstance>();
  createEffect(() => {
    if (form()) {
      form().setValue(props.data);
    }
  });

  return (
    <>
      <DialogHeader>
        {is_null_or_undefined(props.data) ? "新建" : "编辑"}
      </DialogHeader>
      <div>
        <Form
          // value={props.data}
          onRef={setForm}
          onSubmit={handleSaveService}
        >
          <Loading show={loading()}>
            <FormField name={"id"}>
              <FormInputText class="d-input" hidden />
            </FormField>
            <ServiceEditForm />
            <div class="mt-3">
              <DialogAction>
                <DialogCloseButton class="d-btn d-btn-ghost">
                  取消
                </DialogCloseButton>
                <FormSubmit class="d-btn d-btn-primary">保存</FormSubmit>
              </DialogAction>
            </div>
          </Loading>
        </Form>
      </div>
    </>
  );
};

export default () => {
  const [loading, setLoading] = createSignal(false);
  const shell = useDialog();
  const [editing, setEditing] = createSignal<SaveServiceRequest | undefined>(
    undefined
  );
  const [data, { refetch }] = createResource(() => {
    return useClientApi()
      .listAllServices()
      .catch((err) => {
        handleException(err);
        return [] as ServiceDto[];
      });
  });

  const publish_services = () => {
    setLoading(true);
    useClientApi()
      .publish()
      .then(() => {
        SolidSwal2Toast.fire({
          icon: "success",
          title: "发布成功",
        });
      })
      .catch(handleException)
      .finally(() => setLoading(false));
  };

  const check_service = (data: ServiceDto, re_create: boolean) => {
    setLoading(true);
    useServicesApi()
      .checkService(data.id, re_create)
      .then(() =>
        SolidSwal2Toast.fire({ icon: "success", title: "已触发检查" })
      )
      .catch(handleException)
      .finally(() => setLoading(false));
  };

  return (
    <ErrorBoundary
      fallback={
        <button type="button" onClick={() => refetch()}>
          Try again
        </button>
      }
    >
      <Loading show={loading()}>
        <div class="flex flex-1 px-2 gap-1">
          <button
            type="button"
            class="d-btn"
            disabled={data.loading}
            onClick={() => refetch()}
          >
            刷新
          </button>
          <button
            type="button"
            class="d-btn"
            disabled={data.loading}
            onClick={() => shell.show()}
          >
            新建
          </button>
          <button
            type="button"
            class="d-btn d-btn-primary"
            disabled={data.loading}
            onClick={() => publish_services()}
          >
            发布
          </button>
        </div>
        <Table datas={data()} class="d-table">
          <IndexColumn header="No." />
          <TableColumn name={"id"} header="ID" />
          <TableColumn name={"name"} header="Name" />
          <TableColumn name={"matchPath"} header="Match Path" />
          <TableColumn header="Hosts">
            {(data: ServiceDto) => (
              <For each={data.hosts ?? []}>
                {(host) => (
                  <div class="d-badge d-badge-primary d-badge-outline m-1">
                    {host}
                  </div>
                )}
              </For>
            )}
          </TableColumn>
          <TableColumn header="Methods">
            {(data: ServiceDto) => (
              <For each={data.methods ?? []}>
                {(host) => (
                  <div class="d-badge d-badge-sm d-badge-primary d-badge-outline uppercase m-1">
                    {host}
                  </div>
                )}
              </For>
            )}
          </TableColumn>
          <DateTimeColumn name={"lastModified"} header="Last Modified" />
          <TableColumn>
            {(data: ServiceDto) => (
              <div class="flex flex-row gap-1">
                <button
                  type="button"
                  class="d-btn d-btn-ghost d-btn-sm"
                  onClick={() => {
                    shell.show();
                    setEditing(data);
                  }}
                >
                  编辑
                </button>
                <button
                  type="button"
                  class="d-btn d-btn-ghost d-btn-sm"
                  onClick={() => {
                    check_service(data, false);
                  }}
                >
                  检查证书
                </button>
                <button
                  type="button"
                  class="d-btn d-btn-ghost d-btn-sm"
                  onClick={() => {
                    check_service(data, true);
                  }}
                >
                  重新申请
                </button>
              </div>
            )}
          </TableColumn>
        </Table>
        <Dialog
          destroyOnClose
          shell={shell}
          onClose={() => setEditing(undefined)}
        >
          <ServiceEditModalChildren
            onSaved={() => refetch()}
            data={editing() as any}
          />
        </Dialog>
      </Loading>
    </ErrorBoundary>
  );
};
